home *** CD-ROM | disk | FTP | other *** search
- { To Dave Tipton
-
- Example of an interrupt to grab the scan code of each key pressed -
- but not to eat the key. Pass the interrupt back to DOS so it can
- do what it does.
-
- You'll need a look-Up table for the scan codes.
-
- OR - you could eat the key - and then put it back with
- TURBO PROFESSIONAL's Stuff Key. Play around with it.
-
- Compile this and run it. 'Q' Quits. Good Luck.
- }
-
-
- PROGRAM GrabKeys;
-
- { !! Keep F+ and B- for INTERRUPT and FAST Bit testing !! }
- {$F+,B-}
-
- {$R-,I-,S-,L-,D-}
-
- { 18 June 91 }
- { J. Dennis Green - 71620,2427 : Intercept and reRoute Key }
-
- USES
- TpCRT, { TURBO PROFESSIONAL's CRT or CRT }
- DOS; { For Registers, Interrupt, Error }
-
- CONST
- Key_Int = $09;
- Key_Vec : Pointer = NIL; { Swap Key Interrupt }
- Exit_Save : Pointer = NIL; { Swap exit procedure }
- xKey : Word = 0;
-
- RShift = 1; { Constants for Bit Testing xShift }
- LShift = 2;
- CtrlShift = 4;
- AltShift = 8;
- ScrollLock = 16;
- NumLock = 32;
- CapsLock = 64;
- InsertLock = 128;
-
-
- VAR
- ch : Char;
- xShift : Byte Absolute $0040:$0017; { THE information }
- xExtended : Boolean;
-
- { Grab the keyboard interrupt, retrieve the scancode }
- PROCEDURE GrabKey ( Flags,CS,IP,AX,BX,CX,DX,SI,DI,DS,ES,BP : Word );
- INTERRUPT;
- BEGIN
-
- { Read the key directly - but don't eat it }
- xKey:= PortW[$60];
-
- { Give it back }
- InLine
- (
- $FB/ { Interrupts On }
- $A1/>Key_Vec+2/ { Mov AX, [>Key_Vec+2] }
- { Old Vector Seg to AX }
- $8B/$1E/>Key_Vec/ { Mov BX, [>Key_Vec] }
- { Old Vector Ofs to BX }
- $87/$5E/$0E/ { XCHG BX,[BP+$0E] }
- { Swap Ofs w/ Return address }
- $87/$46/$10/ { Xchg AX,[BP+$10] }
- { Swap Set w/ Return address }
- $89/$EC/ { Mov SP,BP ; Undo entry code }
- $5D/ { POP BP }
- $07/ { POP ES }
- $1F/ { POP DS }
- $5F/ { POP DI }
- $5E/ { POP SI }
- $5A/ { POP DX }
- $59/ { POP CX }
- $CB ); { RETF ; In effect JMP to old vector }
- END;
-
-
-
- { Restore the original Key Interrupt }
- PROCEDURE MyExit;
- BEGIN
- ExitProc:= Exit_Save; { Restore normal Exit Procedure }
- InLine ($9C/$FA); { PushF, Cli }
- SetIntVec (Key_Int, Key_Vec ); { Restore original Key interrupt }
- InLine ($FB/$9D); { Sti, Pop Flags }
- END;
-
-
- { Simple example to test for Shifted stuff }
- FUNCTION Shifted: Boolean;
- BEGIN
- Shifted:= ( (xShift and RShift = RShift) or
- (xShift and LShift = LShift) or
- (xShift and CapsLock = CapsLock) );
- END;
-
-
- BEGIN
- GetIntVec (Key_Int, Key_Vec); { Get and Save Key interrupt }
-
- InLine ($FA); { Stop Interrupts }
- SetIntVec (Key_Int, @GrabKey); { ReRoute it to 'my' KeyRead }
- InLine ($FB); { Allow Interrupts }
-
-
- Exit_Save:= ExitProc; { Get and Save normal Exit procedure }
- ExitProc := @MyExit; { ReRoute it to 'my' Exit }
-
-
- { Main Program }
- REPEAT
- IF KeyPressed THEN
- BEGIN
-
- { Lo(xKey) is ScanCode - See TP6 Table B.3 / TP5.5 Table C.3 }
- { xShift is the keyboard Status }
- { Writing CH just for checking }
- { Note that Special Keys - (HOME) - hits this twice. }
- { - xExtended is shown. See ReadKey Explanation }
-
- Write ( Lo(xKey):5, xShift:5, ' ',Shifted,' -> ');
- Ch:= ReadKey;
- IF (Ch = 'Q') THEN Halt(0);
- xExtended:= (Ch = #0);
- Writeln ( ch, ' ', xExtended );
- END;
- UNTIL False;
-
- END.
-
-
-